//
//  WmcCloudAllPhotoVM.swift
//  YPWatermarkCamera
//
//  Created by 赵新 on 2022/3/31.
//

import RxRelay
import UIKit
import YPNetwork

class WmcCloudAllPhotoVM: WmcBaseVM {
    // Lifecycle

    required init() {
        super.init()
        self.pageSize = 20
    }

    // Internal
    
    /// 团队相册
    var teamAblum: WmcMediaTeamAlbumModel?

    /// 界面显示的列表数据
    private(set) var dataSource: [WmcMediaPhotoDayModel] = []

    /// 预览页面数据
    private(set) var browserDataSource: [WmcMedia] = []
    
    /// 接口返回的原始数据
    private(set) var originalDataSource: [WmcMediaPhotoModel] = []
    
    /// 日历数据
    private(set) var dataCalendar: [WmcMediaTakePhotoDayModel] = []

    /// 选择的日期
    var selectedDateStr: String?

    /// 选择的日期
    var selectedDate: Date?

    /// 照片宽高
    let photoWidth: CGFloat = (UIScreen.main.bounds.width - 38) / 3.0

    /// 是否没有数据
    private(set) var hasNoMore: Bool = false

    func fetchPhotoCalendarList(completion: @escaping ([WmcMediaTakePhotoDayModel]) -> Void, failure: @escaping (Error?) -> Void) {
        let endDate = (WmcDateManager.shared.networkDate.value ?? Date()).yp.string("yyyy-MM-dd")
        
        WmcMediaAlbumAPI.fetchTakePhotoCalendar(startDate: "2020-01-01", endDate: endDate).subscribe(onNext: { [weak self] list in
            guard let weakSelf = self else { return }
            var result: [WmcMediaTakePhotoDayModel] = []
            for item in list.reversed() {
                result.append(item)
            }
            weakSelf.dataCalendar = result
            completion(result)
        }, onError: { error in
            failure(error)
        }).disposed(by: rx.disposeBag)
    }

    func refresh(completion: @escaping ([WmcMediaPhotoModel]) -> Void, failure: @escaping (Error) -> Void) {
        fetchPhotoList(pageIndex: 1, pageSize: pageSize, date: selectedDateStr) { [weak self] list in
            guard let weakSelf = self else { return }

            weakSelf.page = 2
            weakSelf.hasNoMore = list.count < weakSelf.pageSize
            weakSelf.originalDataSource = list
            weakSelf.dataSource = weakSelf.sortDataList(array: list)
            var temp: [WmcMedia] = []
            weakSelf.originalDataSource.forEach { model in
                if model.resourceType == 0 {
                    temp.append(WmcImage(url: model.url))
                } else if model.resourceType == 1 {
                    temp.append(WmcVideo(url: model.url))
                }
            }
            weakSelf.browserDataSource = temp
            completion(list)
        } failure: { error in
            failure(error)
        }
    }

    func loadMore(completion: @escaping () -> Void, failure: @escaping (Error) -> Void) {
        fetchPhotoList(pageIndex: self.page, pageSize: pageSize, date: selectedDateStr) { [weak self] list in
            guard let weakSelf = self else { return }

            weakSelf.page += 1
            weakSelf.hasNoMore = list.count < weakSelf.pageSize
            weakSelf.originalDataSource.append(contentsOf: list)
            weakSelf.dataSource = weakSelf.sortDataList(array: weakSelf.originalDataSource)
            var temp: [WmcMedia] = []
            weakSelf.originalDataSource.forEach { model in
                if model.resourceType == 0 {
                    temp.append(WmcImage(url: model.url))
                } else if model.resourceType == 1 {
                    temp.append(WmcVideo(url: model.url))
                }
            }
            weakSelf.browserDataSource = temp
            completion()
        } failure: { error in
            failure(error)
        }
    }

    func deleteImage(index: Int, success: @escaping () -> Void, failure: @escaping (Error?) -> Void) {
        if index < originalDataSource.count {
            let model = originalDataSource[index]
            
            WmcMediaAlbumAPI.deletePhoto(id: model.id).subscribe(onNext: { [weak self] r in
                guard let weakSelf = self else { return }
                weakSelf.originalDataSource.remove(at: index)
                weakSelf.browserDataSource.remove(at: index)
                weakSelf.dataSource = weakSelf.sortDataList(array: weakSelf.originalDataSource)
                success()
            }, onError: { error in
                failure(error)
            }).disposed(by: rx.disposeBag)
            
        } else {
            failure(nil)
        }
    }
    
    func fetchVideoShare(index: Int, success: @escaping (WmcMediaShareModel) -> Void, failure: @escaping (Error?) -> Void) {
        if index < originalDataSource.count {
            let model = originalDataSource[index]
            WmcMediaAlbumAPI.fetchVideoShareInfo(id: model.id).subscribe(onNext: { r in
                success(r)
            }, onError: { error in
                failure(error)
            }).disposed(by: rx.disposeBag)
        } else {
            failure(nil)
        }
    }

    // Private

    private func fetchPhotoList(pageIndex: Int, pageSize: Int, date: String?, completion: @escaping ([WmcMediaPhotoModel]) -> Void, failure: @escaping (Error) -> Void) {
                
        WmcMediaAlbumAPI.fetchPhotoList(page: pageIndex, pageSize: pageSize, startDate: date, endDate: date).subscribe(onNext: { list in
            completion(list)
        }, onError: { error in
            failure(error)
        }).disposed(by: rx.disposeBag)
    }

    private func sortDataList(array: [WmcMediaPhotoModel]) -> [WmcMediaPhotoDayModel] {
        let temp: [WmcMediaPhotoModel] = array.map { model in
            let modelTemp = model
            let timeFields = model.takeTime.components(separatedBy: " ")
            if timeFields.count == 2 {
                var takeDateStr = timeFields[0]
                let fields1 = timeFields[0].components(separatedBy: "-")
                if fields1.count == 3 {
                    takeDateStr = "\(fields1[0])年\(fields1[1])月\(fields1[2])日"
                }
                modelTemp.takeTimeDateStr = takeDateStr
                
                var takeTimeStr = timeFields[1]
                let fields2 = timeFields[1].components(separatedBy: ":")
                if fields2.count == 3 {
                    takeTimeStr = "\(fields2[0]):\(fields2[1])"
                }
                modelTemp.takeTimeStr = takeTimeStr
            }
            return modelTemp
        }

        var days: [WmcMediaPhotoDayModel] = []
        temp.forEach { model in
            let dateIndex = days.firstIndex { dayModel in
                dayModel.date == model.takeTimeDateStr
            }

            if let dateIndex = dateIndex {
                let day = days[dateIndex]

                if let placeTemp = day.placeList.last, placeTemp.address == model.address {
                    placeTemp.photoList.append(model)
                    day.placeList.removeLast()
                    day.placeList.append(placeTemp)
                } else {
                    let place = WmcMediaPhotoPlaceModel()
                    place.photoList.append(model)
                    place.address = model.address
                    place.latitude = model.lat
                    place.longitude = model.lon
                    day.placeList.append(place)
                }

                days[dateIndex] = day
            } else {
                let day = WmcMediaPhotoDayModel()
                day.date = model.takeTimeDateStr

                let place = WmcMediaPhotoPlaceModel()
                place.photoList.append(model)
                place.address = model.address
                place.latitude = model.lat
                place.longitude = model.lon

                day.placeList.append(place)

                days.append(day)
            }
        }

        var result: [WmcMediaPhotoDayModel] = []
        days.forEach { dayModel in
            let dayTemp = dayModel
            var photoCount: Int = 0
            var height: CGFloat = 0.0
            dayModel.placeList.forEach { placeModel in
                placeModel.photoList.forEach { photoModel in
                    photoCount += 1
                }

                let lineCount = placeModel.photoList.count / 3 + (placeModel.photoList.count % 3 > 0 ? 1 : 0)
                let placeHeight = (photoWidth + 3.0) * CGFloat(lineCount) + 39
                height += placeHeight
            }
            dayTemp.count = photoCount
            dayTemp.height = height
            result.append(dayTemp)
        }

        return result
    }
}


extension WmcCloudAllPhotoVM {
    
    /// 设置同步状态
    /// - Parameters:
    ///   - isOn: 是否开启
    ///   - completion: completion description
    func setSynchronization(isOn: Bool, completion: ((_ synStatus: Bool) -> Void)? = nil) {
        // TODO: 马涛
        WmcHudManager.loading()
        WmcPreferenceSettingsManager.queryTeamSyncConfigCache {[weak self] (list: [WmcMediaAlbumConfigurationModel]) in
            guard let weakSelf = self,let teamId = weakSelf.teamAblum?.teamId else { return }
            WmcHudManager.dismiss()
            list.forEach { config in
                if config.albumId == teamId {
                    config.isSync = isOn
                    WmcPreferenceSettingsManager.updateTeamSyncConfig(model: config)
                    completion?(isOn)
                }
            }
        } failure: { error in
            WmcHudManager.toast(error)
            WmcHudManager.dismiss()
        }
    }
    
    /// 获取同步状态
    /// - Returns: description
    func getSysSwitchStatus(succeed: ((_ isSyn: Bool) -> Void)?) -> Void {
        // TODO: 马涛
        WmcPreferenceSettingsManager.queryTeamSyncConfigCache {[weak self] (list: [WmcMediaAlbumConfigurationModel]) in
            guard let weakSelf = self,let teamId = weakSelf.teamAblum?.teamId,let succeed = succeed else { return }
            list.forEach { config in
                if config.albumId == teamId {
                    succeed(config.isSync)
                }
            }
        } failure: { error in
            WmcHudManager.toast(error)
        }
    }
}

extension WmcCloudAllPhotoVM {
    
    /// 修改同步配置
    /// - Returns: description
    func updateSynConfig(isSyn: Bool,succeed:((_ isSyn: Bool) -> Void)?) -> Void {
        guard let albumId = self.teamAblum?.albumId else { return }
        WmcHudManager.loading()
        WmcMediaTeamManagerAPI.updateConfiguration(albumId: albumId, isOpen: isSyn).subscribe {[weak self] res in
            guard let weakSelf = self,let succeed = succeed else { return }
            WmcHudManager.dismiss()
            /// 同步配置
            let config = WmcMediaAlbumConfigurationModel.init()
            config.albumType = 1
            config.isSync = true
            config.name = weakSelf.teamAblum?.name ?? ""
            config.albumId = weakSelf.teamAblum?.teamId ?? 0
            config.busId = weakSelf.teamAblum?.teamId ?? 0
            WmcPreferenceSettingsManager.addTeamSyncConfig(model: config)
            succeed(isSyn)
            WmcNotificationManager.shared.post(type: .synSettingChanged, object: nil)
        } onError: { error in
            WmcHudManager.toast(error.localizedDescription)
            WmcHudManager.dismiss()
            guard let succeed = succeed else {
                return
            }
            succeed(false)
        }.disposed(by: rx.disposeBag)
    }
}
